package com.youlai.boot.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.google.common.collect.Lists;
import com.youlai.boot.common.exception.BusinessException;
import com.youlai.boot.system.enums.RoleTypeEnum;
import com.youlai.boot.system.mapper.RoleMapper;
import com.youlai.boot.system.mapper.UserMapper;
import com.youlai.boot.system.mapper.UserRoleMapper;
import com.youlai.boot.system.model.entity.Role;
import com.youlai.boot.system.model.entity.User;
import com.youlai.boot.system.model.entity.UserRole;
import com.youlai.boot.system.model.vo.OrgUserOptionVO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.youlai.boot.system.mapper.OrgMapper;
import com.youlai.boot.system.mapper.RecycleRequestMapper;
import com.youlai.boot.system.service.OrgService;
import com.youlai.boot.system.model.entity.Org;
import com.youlai.boot.system.model.form.OrgForm;
import com.youlai.boot.system.model.query.OrgQuery;
import com.youlai.boot.system.model.vo.OrgVO;

import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import org.springframework.transaction.annotation.Transactional;

/**
 * 机构管理服务实现类
 *
 * @author youlaitech
 * @since 2025-02-22 15:45
 */
@Service
@RequiredArgsConstructor
public class OrgServiceImpl extends ServiceImpl<OrgMapper, Org> implements OrgService {

    private final UserMapper userMapper;

    private final RoleMapper roleMapper;

    private final UserRoleMapper userRoleMapper;

    private final RecycleRequestMapper recycleRequestMapper;

    /**
     * 获取机构管理分页列表
     *
     * @param queryParams 查询参数
     * @return {@link IPage<OrgVO>} 机构管理分页列表
     */
    @Override
    public IPage<OrgVO> getOrgPage(OrgQuery queryParams) {
        Page<OrgVO> pageVO = this.baseMapper.getOrgPage(
                new Page<>(queryParams.getPageNum(), queryParams.getPageSize()),
                queryParams);
        // 查询机构角色分类
        pageVO.getRecords().forEach(item -> {
            // 查询该机构id对应的用户id
            List<User> users = userMapper.selectList(new LambdaQueryWrapper<User>().eq(User::getOrgId, item.getId()));
            List<User> userList = users.stream().filter(f -> {
                Long roleId = userRoleMapper
                        .selectOne(new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserId, f.getId())).getRoleId();
                String code = roleMapper.selectOne(new LambdaQueryWrapper<Role>().eq(Role::getId, roleId)).getCode();
                return code.equals("RECYCLE_INSTITUTION") || code.equals("HANDLE_INSTITUTION");
            }).toList();
            if (CollUtil.isEmpty(userList)) {
                return;
            }
            User user = userList.get(0);
            Long userId = user.getId();
            // 所属用户
            item.setUserId(userId);
            item.setUsername(user.getUsername());
            // 根据用户id查询对应角色
            Long roleId = userRoleMapper.selectOne(new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserId, userId))
                    .getRoleId();
            Role role = roleMapper.selectOne(new LambdaQueryWrapper<Role>().eq(Role::getId, roleId));
        });
        return pageVO;
    }

    /**
     * 获取机构管理表单数据
     *
     * @param id 机构管理ID
     * @return
     */
    @Override
    public OrgForm getOrgFormData(Long id) {
        OrgForm form = new OrgForm();
        Org entity = this.getById(id);

        BeanUtil.copyProperties(entity, form);
        if (StrUtil.isNotBlank(entity.getCertification())) {
            form.setCertification(Lists.newArrayList(entity.getCertification()));
        }

        // 1. 查询该机构隶属的用户及其角色
        List<User> users = userMapper.selectList(new LambdaQueryWrapper<User>().eq(User::getOrgId, id));
        if (CollUtil.isNotEmpty(users)) {
            List<Long> userIds = users.stream().map(User::getId).toList();
            if (CollUtil.isNotEmpty(userIds)) {
                List<UserRole> userRoles = userRoleMapper
                        .selectList(new LambdaQueryWrapper<UserRole>().in(UserRole::getUserId, userIds));
                Map<Long, String> userCodeMap = userRoles.stream()
                        .collect(Collectors.toMap(UserRole::getUserId,
                                ur -> roleMapper.selectById(ur.getRoleId()).getCode()));
                userCodeMap.forEach((k, v) -> {
                    if (v.equals(RoleTypeEnum.RECYCLE.getCode())) {
                        form.setUserId(k);
                        form.setUsername(userMapper.selectById(k).getUsername());
                    }
                });
            }

        }
        return form;
    }

    /**
     * 新增机构管理
     *
     * @param formData 机构管理表单对象
     * @return
     */
    /**
     * 新增机构管理
     *
     * @param formData 机构管理表单对象
     * @return 操作是否成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveOrg(OrgForm formData) {
        try {
            // 1.保存机构信息

            Org entity = new Org();
            BeanUtil.copyProperties(formData, entity);
            if (CollUtil.isNotEmpty(formData.getCertification())) {
                entity.setCertification(formData.getCertification().get(0));
            } else {
                entity.setCertification("");
            }
            entity.setStatus(0);
            this.save(entity);

            // 2. 修改用户隶属机构id
            if (formData.getUserId() != null) {
                Long userId = formData.getUserId();
                User user = userMapper.selectById(userId);
                if (user == null) {
                    throw new IllegalArgumentException("用户不存在");
                }

                Long orgId = entity.getId();
                user.setOrgId(orgId);
                userMapper.updateById(user);

                // 修改用户所属角色
                UserRole userRole = userRoleMapper
                        .selectOne(new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserId, userId));
                if (userRole != null) {
                    Role role = roleMapper
                            .selectOne(
                                    new LambdaQueryWrapper<Role>().eq(Role::getCode, RoleTypeEnum.RECYCLE.getCode()));
                    if (role == null) {
                        throw new IllegalStateException("角色未找到");
                    }
                    userRole.setRoleId(role.getId());
                    userRoleMapper.update(userRole,
                            new LambdaUpdateWrapper<UserRole>().eq(UserRole::getUserId, userId));
                }
            }

            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 更新机构管理
     *
     * @param id       机构管理ID
     * @param formData 机构管理表单对象
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateOrg(Long id, OrgForm formData) {
        // 1. 修改机构数据
        Org entity = new Org();
        BeanUtil.copyProperties(formData, entity);
        if (CollUtil.isNotEmpty(formData.getCertification())) {
            entity.setCertification(formData.getCertification().get(0));
        } else {
            entity.setCertification("");
        }
        this.updateById(entity);
        // 2. 修改机构隶属的用户角色
        if (formData.getUserId() != null) {
            // 2.1清空原机构隶属用户
            User oldUser = userMapper.selectById(formData.getOldUserId());
            oldUser.setOrgId(null);
            userMapper.updateById(oldUser);
            // 2.2修改新机构隶属用户
            User user = userMapper.selectById(formData.getUserId());
            user.setOrgId(id);
            userMapper.updateById(user);
        }
        // 3.修改机构分类(修改改用户角色)
        // 3.1清空原机构隶属用户的角色
        UserRole oldUserRole = userRoleMapper
                .selectOne(new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserId, formData.getOldUserId()));
        if (oldUserRole != null) {
            oldUserRole.setRoleId(roleMapper
                    .selectOne(new LambdaQueryWrapper<Role>().eq(Role::getCode, RoleTypeEnum.GUEST.getCode()))
                    .getId());
            userRoleMapper.update(oldUserRole,
                    new LambdaUpdateWrapper<UserRole>().eq(UserRole::getUserId, formData.getOldUserId()));
        }
        // 3.2 修改新隶属用户角色
        Long roleId = roleMapper
                .selectOne(new LambdaQueryWrapper<Role>().eq(Role::getCode, RoleTypeEnum.RECYCLE.getCode()))
                .getId();
        UserRole userRole = userRoleMapper
                .selectOne(new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserId, formData.getUserId()));
        userRole.setRoleId(roleId);
        userRoleMapper.update(userRole,
                new LambdaUpdateWrapper<UserRole>().eq(UserRole::getUserId, formData.getUserId()));
        return true;
    }

    /**
     * 删除机构管理
     *
     * @param ids 机构管理ID，多个以英文逗号(,)分割
     * @return
     */
    @Override
    public boolean deleteOrgs(String ids) {
        Assert.isTrue(StrUtil.isNotBlank(ids), "删除的机构管理数据为空");
        // 逻辑删除
        List<Long> idList = Arrays.stream(ids.split(","))
                .map(Long::parseLong)
                .toList();
        return this.removeByIds(idList);
    }

    @Override
    @Transactional(readOnly = true)
    public List<OrgUserOptionVO> getWorkersByOrgId(String orgId) {
        Assert.notNull(orgId, () -> new BusinessException("机构ID不能为空"));

        // 带缓存的角色查询
        Role workerRole = Optional.ofNullable(roleMapper.selectOne(new LambdaQueryWrapper<Role>()
                .eq(Role::getCode, RoleTypeEnum.WORKER.getCode())))
                .orElseThrow(() -> new BusinessException("WORKER角色未配置"));

        // 分页查询用户ID防止大IN查询
        List<Long> userIds = userRoleMapper.selectList(new LambdaQueryWrapper<UserRole>()
                .select(UserRole::getUserId)
                .eq(UserRole::getRoleId, workerRole.getId())
                .groupBy(UserRole::getUserId))
                .stream()
                .map(UserRole::getUserId)
                .collect(Collectors.toList());

        if (CollectionUtil.isEmpty(userIds)) {
            return Collections.emptyList();
        }

        // 分批查询用户信息
        return Lists.partition(userIds, 500).stream()
                .parallel()
                .flatMap(batch -> userMapper.selectBatchIds(batch).stream()
                        .filter(u -> ObjectUtil.isNotNull(u.getOrgId()))
                        .filter(u -> u.getOrgId().equals(Long.parseLong(orgId))))
                .map(u -> OrgUserOptionVO.builder().userId(u.getId()).username(u.getUsername()).build())
                .collect(Collectors.toList());
    }

    @Override
    @Transactional(readOnly = true)
    public List<OrgUserOptionVO> getWorkersByRequestId(String requestId) {
        Assert.notNull(requestId, () -> new BusinessException("回收请求ID不能为空"));
        Long orgId = recycleRequestMapper.selectById(requestId).getOrgId();
        Assert.notNull(orgId, () -> new BusinessException("机构ID不能为空"));
        // 带缓存的角色查询
        Role workerRole = Optional.ofNullable(roleMapper.selectOne(new LambdaQueryWrapper<Role>()
                .eq(Role::getCode, RoleTypeEnum.WORKER.getCode())))
                .orElseThrow(() -> new BusinessException("WORKER角色未配置"));

        // 分页查询用户ID防止大IN查询
        List<Long> userIds = userRoleMapper.selectList(new LambdaQueryWrapper<UserRole>()
                .select(UserRole::getUserId)
                .eq(UserRole::getRoleId, workerRole.getId())
                .groupBy(UserRole::getUserId))
                .stream()
                .map(UserRole::getUserId)
                .collect(Collectors.toList());

        if (CollectionUtil.isEmpty(userIds)) {
            return Collections.emptyList();
        }

        // 分批查询用户信息
        return Lists.partition(userIds, 500).stream()
                .parallel()
                .flatMap(batch -> userMapper.selectBatchIds(batch).stream()
                        .filter(u -> u.getOrgId().equals(orgId)))
                .map(u -> OrgUserOptionVO.builder().userId(u.getId()).username(u.getUsername()).build())
                .collect(Collectors.toList());
    }

    /**
     * 新建机构时，获取所有工作人员
     * 
     * @return
     */
    @Override
    public List<OrgUserOptionVO> getAllWorkerOptions() {
        Long roleId = roleMapper
                .selectOne(new LambdaQueryWrapper<Role>().eq(Role::getCode, RoleTypeEnum.WORKER.getCode())).getId();
        List<Long> userIds = userRoleMapper
                .selectList(new LambdaQueryWrapper<UserRole>().eq(UserRole::getRoleId, roleId)).stream()
                .map(UserRole::getUserId).toList();
        if (CollectionUtil.isEmpty(userIds)) {
            return Collections.emptyList();
        }
        List<OrgUserOptionVO> list = userMapper.selectBatchIds(userIds).stream().map(u -> {
            OrgUserOptionVO vo = new OrgUserOptionVO();
            vo.setUserId(u.getId());
            vo.setUsername(u.getUsername());
            return vo;
        }).toList();
        return list;
    }

}
